#include"tree.h"
#include<stdio.h>
#include<stdlib.h>

void TreeCreate(Tree* t,int size){//初始化一棵树
    t->nodes = malloc(sizeof(TreeNode)*size);
    //nodes 实际上可以认为是包含了所有树节点的数组
    //通过id在数组中索引可以在O(1)的时间复杂度下取到对应的树节点的地址
    t->root = NULL;
}
//这种设计的二叉树是吧所有的节点都存储在链表中？
void AddTreeChild(TreeNode* parent,TreeNode* child){ //给当前节点添加一个孩子节点
    ListNode* childNode = malloc(sizeof(ListNode));
    childNode->next = NULL;
    childNode->data = child;//链表是的数据是树节点
    if(parent->childrenHead==NULL){//判断当前树节点的孩子链表是否为空
        parent->childrenHead = childNode;//如果为空设置为当前树节点的孩子链表的表头
    }else{
        childNode->next = parent->childrenHead;
        parent->childrenHead = childNode;//头插法
    }
}//实际上这一步的操作就是树添加一条边的操作

void TreeDestroy(Tree* t){
    free(t->nodes);
    t->nodes = NULL;
    t->root = NULL;
}

TreeNode* TreeGetNode(Tree* t,int id){//通过id快速找到对应的节点
    return &t->nodes[id];
}
 
void TreeSetRoot(Tree* t,int id){//设置任意节点为根节点
    t->root = TreeGetNode(t,id);
}

void TreeAddChild(Tree* t,int parentId,int ChildId){//通过索引来添加树边
    TreeNode* parentNode = TreeGetNode(t,parentId);
    TreeNode* ChildNode = TreeGetNode(t,ChildId);
    AddTreeChild(parentNode,ChildNode);
}

//由于树节点上面的数据不仅仅是个编号,还可能是字符或者是其他的更加丰富的数据
//所以需要有一个接口来完成这一步映射
void TreeAssignData(Tree*t ,int id,eleType data){
    TreeGetNode(t,id)->data = data;
}

void TreePrint(Tree* t,TreeNode* node){//从一棵树的指定节点开始遍历?
    if(node == NULL){
        node = t->root;
    }
    printf("%c",node->data); 
    ListNode* tmp = node->childrenHead;
    while (tmp){
        TreePrint(t,tmp->data);
        tmp = tmp->next;
    }
}